package com.mall.module.product.service.Impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mall.common.enums.CommonStatusEnum;
import com.mall.common.exception.BusinessException;
import com.mall.common.result.ResultCode;
import com.mall.common.util.SecurityUtils;
import com.mall.module.product.domain.dto.ProductCategoryDTO;
import com.mall.module.product.domain.entity.ProductCategory;
import com.mall.module.product.domain.vo.ProductCategoryVO;
import com.mall.module.product.mapper.ProductCategoryMapper;
import com.mall.module.product.service.ProductCategoryService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品分类服务实现类 - 企业级优化版本
 */
@Service
@RequiredArgsConstructor
public class ProductCategoryServiceImpl implements ProductCategoryService {

    private static final Logger log = LoggerFactory.getLogger(ProductCategoryServiceImpl.class);
    private static final int MAX_CATEGORY_LEVEL = 3;

    private final ProductCategoryMapper categoryMapper;

    @Override
    public PageInfo<ProductCategoryVO> page(int pageNum, int pageSize, String name, Integer status) {
        PageHelper.startPage(pageNum, pageSize);
        List<ProductCategory> list = categoryMapper.selectPage(name, status);
        return new PageInfo<>(convertToVOList(list));
    }

    @Override
    public List<ProductCategoryVO> tree(Long parentId) {
        // 1. 一次性加载所有分类数据
        List<ProductCategory> allCategories = categoryMapper.selectList();
        List<ProductCategoryVO> allVos = convertToVOList(allCategories);

        // 2. 构建ID到分类的映射
        Map<Long, ProductCategoryVO> categoryMap = allVos.stream()
            .collect(Collectors.toMap(ProductCategoryVO::getId, vo -> vo));

        // 3. 确定根节点ID
        Long rootId = (parentId == null) ? 0L : parentId;

        // 4. 构建树形结构
        List<ProductCategoryVO> rootNodes = new ArrayList<>();
        for (ProductCategoryVO vo : allVos) {
            Long currentParentId = vo.getParentId() != null ? vo.getParentId() : 0L;

            if (currentParentId.equals(rootId)) {
                rootNodes.add(vo);
            } else {
                ProductCategoryVO parent = categoryMap.get(currentParentId);
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(vo);
                }
            }
        }

        // 5. 排序树节点
        sortTreeNodes(rootNodes);
        return rootNodes;
    }

    /**
     * 递归排序树节点
     */
    private void sortTreeNodes(List<ProductCategoryVO> nodes) {
        if (CollectionUtils.isEmpty(nodes)) return;

        // 当前层排序
        nodes.sort(Comparator.comparingInt(ProductCategoryVO::getOrderNum));

        // 递归排序子节点
        for (ProductCategoryVO node : nodes) {
            if (CollectionUtils.isNotEmpty(node.getChildren())) {
                sortTreeNodes(node.getChildren());
            }
        }
    }

    @Override
    public ProductCategoryVO getDetail(Long id) {
        ProductCategory category = categoryMapper.selectById(id);
        if (category == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "分类不存在");
        }
        return convertToVO(category);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long add(ProductCategoryDTO dto) {
        validateCategoryDTO(dto);

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(dto, category);

        // 设置层级
        setCategoryLevel(category, dto.getParentId());
        // 设置默认值
        if (category.getOrderNum() == null) {
            category.setOrderNum(0);
        }
        if (category.getStatus() == null) {
            category.setStatus(CommonStatusEnum.ENABLED.getValue());
        }


        // 设置操作信息
        setCreatorInfo(category);

        categoryMapper.insert(category);
        log.info("创建商品分类成功, ID: {}, 名称: {}", category.getId(), category.getName());
        return category.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ProductCategoryDTO dto) {
        if (dto.getId() == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "分类ID不能为空");
        }

        ProductCategory existing = categoryMapper.selectById(dto.getId());
        if (existing == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "分类不存在");
        }

        validateCategoryDTO(dto);

        ProductCategory category = new ProductCategory();
        BeanUtils.copyProperties(dto, category);

        // 如果修改了父ID，重新计算层级
        if (!Objects.equals(existing.getParentId(), dto.getParentId())) {
            setCategoryLevel(category, dto.getParentId());
        }

        // 设置更新信息
        setUpdaterInfo(category);

        categoryMapper.update(category);
        log.info("更新商品分类成功, ID: {}", category.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        if (id == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "分类ID不能为空");
        }

        // 检查是否存在子分类
        if (categoryMapper.hasChildren(id)) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "存在子分类，无法删除");
        }

        // 执行删除
        categoryMapper.deleteById(id);
        log.warn("删除商品分类, ID: {}", id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchDelete(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "ID列表不能为空");
        }

        // 检查是否存在子分类
        List<Long> categoriesWithChildren = categoryMapper.findCategoriesWithChildren(ids);
        if (CollectionUtils.isNotEmpty(categoriesWithChildren)) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "存在子分类的分类无法删除: " + categoriesWithChildren);
        }

        // 批量删除
        categoryMapper.deleteBatchIds(ids);
        log.warn("批量删除商品分类, ID列表: {}", ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateStatus(List<Long> ids, Integer status) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "ID列表不能为空");
        }

        // 校验状态值
        if (!CommonStatusEnum.isValid(status)) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "无效的状态值: " + status);
        }

        categoryMapper.updateBatchStatus(ids, status);
        log.info("批量更新分类状态, ID列表: {}, 状态: {}", ids, status);
    }

    /**
     * 设置分类层级
     */

    private void setCategoryLevel(ProductCategory category, Long parentId) {
        // 1. 顶级分类处理 (parentId为null或0)
        if (parentId == null || parentId == 0L) {
            category.setParentId(null);
            category.setLevel(1);
            return;
        }

        // 2. 验证父分类存在性
        ProductCategory parent = categoryMapper.selectById(parentId);
        if (parent == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "父分类不存在");
        }

        // 3. 层级合法性检查
        if (parent.getLevel() >= 3) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, "分类层级不能超过3级");
        }

        // 4. 设置当前分类层级
        category.setLevel(parent.getLevel() + 1);
    }

    /**
     * 设置创建者信息
     */
    private void setCreatorInfo(ProductCategory category) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        category.setCreatorId(currentUserId);
        category.setCreateTime(LocalDateTime.now());
    }

    /**
     * 设置更新者信息
     */
    private void setUpdaterInfo(ProductCategory category) {
        Long currentUserId = SecurityUtils.getCurrentUserId();
        category.setUpdaterId(currentUserId);
        category.setUpdateTime(LocalDateTime.now());
    }

    /**
     * 将实体列表转换为VO列表
     */
    private List<ProductCategoryVO> convertToVOList(List<ProductCategory> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return Collections.emptyList();
        }
        return entities.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    /**
     * 将实体转换为VO
     */
    private ProductCategoryVO convertToVO(ProductCategory entity) {
        if (entity == null) {
            return null;
        }
        ProductCategoryVO vo = new ProductCategoryVO();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }

    private void validateCategoryDTO(ProductCategoryDTO dto) {
        // 基础校验
        if (StringUtils.isBlank(dto.getName())) {
            throw new IllegalArgumentException("分类名称不能为空");
        }

        // 层级关系校验
        if (dto.getParentId() != null && dto.getParentId() != 0) {
            int parentCount = categoryMapper.existsById(dto.getParentId());
            if (parentCount == 0) {
                throw new BusinessException(ResultCode.DATA_NOT_EXISTED,"指定的父分类不存在");

            }
        }

        // 防止层级过深（根据业务需求）
        if (dto.getLevel() != null && dto.getLevel() > MAX_CATEGORY_LEVEL) {
            throw new BusinessException(ResultCode.DATA_NOT_EXISTED, MAX_CATEGORY_LEVEL + "级");

        }
    }
}